import java.util.Iterator;
import java.util.Vector;

public class Spelronde
{	private Vector<Deelname> deelnames;
	private KaartStapel kaartstapel;
	private int minInzet;
	private int maxInzet;
	private GeverDeelname dealer;
	private int aantalDeelnames = 0;

	public Spelronde(Speler[] spelers, int min, int max,KaartStapel ks)
	{
		deelnames = new Vector<Deelname>();
		minInzet = min;
		maxInzet = max;
		kaartstapel = ks;
		for (int i = 0; i < spelers.length; i++){
			deelnames.add(new SpelerDeelname(spelers[i]));
			//aantalSpelers++;
		}
		dealer = new GeverDeelname();
		deelnames.add(dealer);
	}
	
	/**
	 * trekt een kaart van de kaartstapel en returned deze
	 * 
	 * @return Kaart
	 */
	public Kaart hit(){
		return kaartstapel.trekKaart();
	}
	
	/**
	 * maakt een nieuw spelerdeelname aan met een Kaart
	 * van spelerDeelname 1 en geeft deze mee met de inzet en de speler.
	 * @param d
	 */
	public void split(Deelname d) throws GeenGeldException{
		try
		{	SpelerDeelname sd1 = (SpelerDeelname) d;
			int index = deelnames.indexOf(d);
			if(sd1.getInzet() - sd1.getInsurance() <= sd1.getSaldo())
			{	SpelerDeelname sd2 = new SpelerDeelname(sd1.splitKaart(), 0, sd1.getSpeler(), 2);
				sd2.setInzet(sd1.getInzet() - sd1.getInsurance());
				deelnames.insertElementAt(sd2, index+1);
				aantalDeelnames++;
			}
			else
				throw new GeenGeldException("Je hebt niet genoeg geld.");
		}
		catch(GeenGeldException gge)
		{	throw gge;
		}
	}
	
	/**
	 * Set het aantal deelnames die mee doen per ronde, dit kan verschillen met
	 * het aantal spelers omdat de spelers onthouden worden maar de deelnames niet
	 * als de spelers geen geld meer hebben.
	 * @param aantalDeel
	 */
	public void setAantalDeelnames(int aantalDeel){
		aantalDeelnames = aantalDeel;
	}
	
	/**
	 * Zet het bedrag in voor de meegegeven deelname en kijkt ook gelijk of
	 * de inzet wel voldoet aan de van te voren af gesproken waarden van
	 * min inzet en max inzet.
	 * @param d
	 * @param inzet
	 * @throws GeenGeldException
	 */
	public void inzetten(Deelname d, double inzet)throws GeenGeldException{
		if(inzet <= maxInzet && inzet >= minInzet){
			SpelerDeelname sd = (SpelerDeelname) d;
				sd.setInzet(inzet);
		}
		else
			throw new IllegalArgumentException("Geen geldige inzet. Minimale inzet: "+ minInzet + ". Maximale inzet: " + maxInzet + ".");
	}
	
	/**
	 * Roept Double down aan voor de meegegeven deelname
	 * @param d
	 * @throws GeenGeldException
	 */
	public void doubledown(Deelname d)throws GeenGeldException
	{	SpelerDeelname sd = (SpelerDeelname) d;
		sd.doubleDown();
	}

	/**
	 * Roept insurance aan voor de meegegeven deelname
	 * @param d
	 * @throws GeenGeldException
	 */
	public void insurance(Deelname d)throws GeenGeldException
	{
		SpelerDeelname sd = (SpelerDeelname) d;
			sd.setInsurance();
	}
	
	/**
	 * Berekent De verlies of winst van elke deelname in de spelronde.
	 * Deze methode word aangeroepen na het einde van een ronde en berekent
	 * dus wat iedereen wint of verliest. Het vergelijkt dus de punten van de
	 * speler met de van de dealer, Kijkt of er insurance staat en of de dealer
	 * dan BJ heeft. En roept voor elke deelname wint(inzet) of verleist aan. Vervolgens
	 * worden al deze gegevens in een multi-demensionale array van strings gegooid en word
	 * ScoreController aangeroepen en deze parameters mee gegeven.
	 * @return str[][]
	 */
	public String[][] berekenRonde(){
		GeverDeelname dealer = (GeverDeelname) deelnames.lastElement();
		String[][] data = new String[deelnames.size()][3];
		int ii = 0;
		for (Iterator<Deelname> i = deelnames.iterator(); i.hasNext();)
		{	try 
			{	SpelerDeelname speler = (SpelerDeelname) i.next();
				try
				{	speler.checkBlackJack();
					if ((speler.getPunten() > dealer.getPunten() || dealer.getPunten() > 21) && speler.getPunten() < 22)
					{	// Speler wint
						if(speler.getInsurance() != 0)
						{	speler.verliest(speler.getInsurance());
							System.out.println(speler.getNaam() + " verliest insurance: " + speler.getInsurance());
						}
						speler.wint(speler.getInzet() - speler.getInsurance());
						System.out.println(speler.getNaam() + " wint " + (speler.getInzet() - speler.getInsurance()));
					}
					else
					{	// Dealer wint
						//Check of dealer BJ heeft en player is insured
						try
						{	dealer.checkBlackJack();
							if(speler.getInsurance() != 0)
							{	speler.verliest(speler.getInsurance());
								System.out.println(speler.getNaam() + " verliest insurance: " + speler.getInsurance());
							}
						}
						catch(BlackJackException be)
						{	if(speler.getInsurance() != 0)
							{	speler.wintInsurance(speler.getInsurance());
								System.out.println(speler.getNaam() + " is insured en wint " + (speler.getInsurance() * 2));
							}
						}
						speler.verliest(speler.getInzet() - speler.getInsurance());
						System.out.println(speler.getNaam() + " verliest " + (speler.getInzet() - speler.getInsurance()));
					}
				}
				catch (BlackJackException bje)
				{	try
					{	dealer.checkBlackJack();
						if(speler.getInsurance() != 0)
						{	speler.verliest(speler.getInsurance());
							System.out.println(speler.getNaam() + " verliest insurance: " + speler.getInsurance());
						}
						speler.wintBlackjack(speler.getInzet() - speler.getInsurance());
						System.out.println(speler.getNaam() + " wint " + ((speler.getInzet() - speler.getInsurance())) * 1.5);
					}
					catch(BlackJackException be)
					{	if(speler.getInsurance() != 0)
						{	speler.wintInsurance(speler.getInsurance());
							System.out.println(speler.getNaam() + " is insured en wint " + (speler.getInsurance() * 2));
						}
						speler.verliest(speler.getInzet() - speler.getInsurance());
						System.out.println(speler.getNaam() + " verliest " + (speler.getInzet() - speler.getInsurance()));
					}
				}
				String s = speler.getNaam();
				data[ii][0] = s;
				String sc = speler.getScore()+"";
				data[ii][1] = sc;
				String saldo = speler.getSaldo()+"";
				data[ii][2] = saldo;
				ii++;
			}
			catch (ClassCastException cce)
			{
			}
		}
		data[ii][0] = "";
		data[ii][1] = "";
		return data;
	}
	
	/**
	 * Returned de Speler deelname voor de meegegeven Speler
	 * @param s Speler
	 * @return SpelerDeelname
	 */
	public Vector<SpelerDeelname> getDeelnamesBySpeler(Speler s){
		Vector<SpelerDeelname> spelers = new Vector<SpelerDeelname>();
		for (Iterator<Deelname> i = deelnames.iterator(); i.hasNext();){
			try {
				SpelerDeelname speler = (SpelerDeelname) i.next();
				if (speler.getSpeler() == s){
					spelers.add(speler);
				}
			}catch (ClassCastException cce){}
		}
		return spelers;
	}

	public Vector<Deelname> getDeelnames()
	{	return deelnames;		
	}
	public GeverDeelname getDealer(){
		return dealer;
	}
	public int getAantalDeelnames(){
		return aantalDeelnames;
	}
}